from flask import Blueprint, render_template, request, jsonify
from flask_login import login_required, current_user
from sqlalchemy import desc, func
from applications.view.plugin import get_current_time
from applications.common import curd
from applications.common.curd import enable_status, disable_status
from applications.common.utils.http import table_api, fail_api, success_api
from applications.common.utils.rights import authorize
from applications.common.utils.validate import str_escape
from applications.extensions import db
from applications.models import Device, Device_borrow, User, user_role
from datetime import datetime

bp = Blueprint('device', __name__, url_prefix='/device')


# 设备管理
@bp.get('/')
@authorize("system:device:main")
def main():
    return render_template('system/device/device.html')



# 设备信息分页查询
@bp.get('/data')
@authorize("system:device:main")
def data():
    # 获取请求参数
    deviceName = str_escape(request.args.get('deviceName', type=str))

    producer = str_escape(request.args.get('producer', type=str))

    filters = []
    if deviceName:
        filters.append(Device.deviceName.contains(deviceName))
    if producer:
        filters.append(Device.producer.contains(producer))

    query = db.session.query(
        Device
    ).filter(*filters).layui_paginate()


    return table_api(
        data=[{
            'id': device.id,
            'deviceName': device.deviceName,
            'typeNum': device.typeNum,
            'producer': device.producer,
            'enable': device.enable,
            'purchase_at': str(device.purchase_at),
            'warranty': device.warranty,
            'status': device.status
        } for device in query.items],
        count=query.total)

# 设备增加
@bp.get('/add')
@authorize("system:device:add", log=True)
def add():
    device = Device.query.all()
    return render_template('system/Device/add.html', device=device)


@bp.post('/save')
@authorize("system:device:add", log=True)
def save():
    req_json = request.get_json(force=True)
    deviceName = str_escape(req_json.get('deviceName'))
    details = str_escape(req_json.get('details'))
    purchase_date = str_escape(req_json.get('purchase_date'))
    producer = str_escape(req_json.get('producer'))
    enable = str_escape(req_json.get('enable'))
    size = str_escape(req_json.get('size'))
    if not deviceName or not purchase_date or not producer or not enable or not size:
        return fail_api(msg="相关信息不得为空")

    purchase_date = datetime.strptime(purchase_date, "%Y-%m-%d")
    details = '无' if not details else details

    try:
        device = Device(deviceName=deviceName, warranty=details, purchase_at=purchase_date, producer=producer,
                        enable=enable, typeNum=size)
        db.session.add(device)
        db.session.commit()
    except:
        db.session.rollback()
        return fail_api(msg="字段格式错误")
    return success_api(msg="增加成功")


# 删除设备
@bp.delete('/remove/<int:id>')
@authorize("system:device:remove", log=True)
def delete(id):
    res = Device.query.filter_by(id=id).delete()
    db.session.commit()
    if not res:
        return fail_api(msg="删除失败")
    return success_api(msg="删除成功")


#  编辑设备，这里主要是用来传递页面
@bp.get('/edit/<int:id>')
@authorize("system:device:edit", log=True)
def edit(id):
    device = curd.get_one_by_id(Device, id)
    return render_template('system/device/edit.html', device=device)


#  编辑设备信息
@bp.put('/update')
@authorize("system:device:edit", log=True)
def update():
    req_json = request.get_json(force=True)
    print(req_json)
    id = str_escape(req_json.get('id'))
    deviceName = str_escape(req_json.get('deviceName'))
    details = str_escape(req_json.get('details'))
    purchase_date = str_escape(req_json.get('purchase_date'))
    producer = str_escape(req_json.get('producer'))
    enable = str_escape(req_json.get('enable'))
    size = str_escape(req_json.get('size'))
    purchase_date = datetime.strptime(purchase_date, "%Y-%m-%d %H:%M:%S")

    if not deviceName or not purchase_date or not producer or not enable or not size:
        return fail_api(msg="设备名称生产商购买时间可用尺寸不得为空")

    Device.query.filter_by(id=id).update({'deviceName': deviceName, 'warranty': details,
                                          'purchase_at': purchase_date, 'producer': producer,
                                          'enable': enable, 'typeNum': size})
    db.session.commit()
    return success_api(msg="更新成功")

# 启用
@bp.put('/enable')
@authorize("system:device:edit", log=True)
def enable():
    _id = request.get_json(force=True).get('deviceId')
    if _id:
        res = enable_status(model=Device, id=_id)
        if not res:
            return fail_api(msg="出错啦")
        return success_api(msg="启动成功")
    return fail_api(msg="数据错误")


# 报废设备
@bp.put('/disable')
@authorize("system:device:edit", log=True)
def dis_enable():
    _id = request.get_json(force=True).get('deviceId')
    if _id:
        res = disable_status(model=Device, id=_id)
        if not res:
            return fail_api(msg="出错啦")
        return success_api(msg="禁用成功")
    return fail_api(msg="数据错误")


'''
详情页面
'''
@bp.get('/records')
@authorize("system:device:records")
def records():
    return render_template('system/device/records.html')


def query_record_result(filters):
    role = db.session.query(user_role).filter_by(user_id=current_user.id).first()
    # 如果是普通用户就只能看自己的使用记录
    if role[-1] == 2:
        query = db.session.query(
            Device_borrow, Device, User
        ).filter(
            Device_borrow.deviceId == Device.id,
            Device_borrow.borrowerId == User.id,
            User.id == current_user.id,  # 只能看自己的
            *filters
        ).layui_paginate()
    else:
        query = db.session.query(
            Device_borrow, Device, User
        ).filter(
            Device_borrow.deviceId == Device.id,
            Device_borrow.borrowerId == User.id,
            *filters
        ).layui_paginate()
    return query



# 设备使用记录信息分页查询
@bp.get('/records/data')
@authorize("system:device:records")
def records_data():
    # 获取请求参数
    deviceId = str_escape(request.args.get('deviceId', type=str))

    status = str_escape(request.args.get('status', type=str))

    filters = []
    if deviceId:
        filters.append(Device_borrow.deviceId == deviceId)
    if status:
        filters.append(Device_borrow.status == status)

    query = query_record_result(filters)
    # print(query.items[0])
    # (< Device_borrow 1 >, < Device 2 >, < User 1 >)

    return table_api(
        data=[{
            'id': device_borrow[0].id,
            'borrowerId': device_borrow[0].borrowerId,
            'borrowerName': device_borrow[2].username,
            'deviceId': device_borrow[0].deviceId,
            'deviceName': device_borrow[1].deviceName,
            'borrow_at': str(device_borrow[0].borrow_at),
            'return_at': str(device_borrow[0].return_at),
            'status': device_borrow[0].status,
            'pay_money': device_borrow[0].pay_money

        } for device_borrow in query.items],
        count=query.total)

@bp.put('/borrow/<int:id>')
@authorize("system:device:borrow", log=True)
def borrow(id):
    device = curd.get_one_by_id(Device, id)
    if device.status == 0:
        return fail_api(msg="设备已经借出")
    elif device.enable == 0:
        return fail_api(msg="设备已经报废")

    device_borrow = Device_borrow(
        deviceId=id,
        borrowerId=current_user.id,
        borrow_at=get_current_time(),
        status=1,
    )

    Device.query.filter_by(id=id).update({'status': 0})
    db.session.add(device_borrow)
    db.session.commit()
    return success_api(msg="借出成功")

@bp.get('/back')
@authorize("system:device:back", log=True)
def return_device_main():
    return render_template('system/device/back.html')

def return_data(query):
    result_data = {
        'success': True,
        'data': {
            'id': query.id,
            'borrowerId': query.borrowerId,
            'deviceId': query.deviceId,
            'borrow_at': str(query.borrow_at),
            'status': query.status,
            'pay_money': 0
        },
        'msg': "归还成功"
    }
    if query.status == 1:
        # 同时更新对应的数据库
        Device.query.filter_by(id=query.deviceId).update({'status': 1})
        # 同时把借用信息归纳为归还
        Device_borrow.query.filter_by(id=query.id).update({'status': 2, 'pay_money': 0, 'return_at': get_current_time()})
        db.session.commit()
    if query.status == 0:
        result_data['data']['pay_money'] = (datetime.now() - query.borrow_at).days - 2
        result_data['msg'] = "待支付"
    return result_data

@bp.post('/back_device')
@authorize("system:device:back", log=True)
def return_device():
    get_json = request.get_json(force=True)
    deviceId = get_json.get('deviceId')
    borrow_at = get_json.get('borrow_at')
    filters = []
    if deviceId:
        filters.append(Device_borrow.deviceId == deviceId)
    elif borrow_at:
        specific_day = datetime.strptime(borrow_at, '%Y-%m-%d')
        filters.append(func.DATE(Device_borrow.borrow_at) == specific_day.date())

    query = db.session.query(
        Device_borrow
    ).filter(Device_borrow.borrowerId == current_user.id, Device_borrow.status != 2, *filters).first()

    if query:
        result_data = return_data(query)
    else:
        result_data = {'success': False, 'msg': '未找到相关数据'}

    return jsonify(result_data)

@bp.put('/back/pay')
@authorize("system:device:back", log=True)
def pay():
    get_json = request.get_json(force=True)
    id = get_json.get('id')
    pay_money = get_json.get('pay_money')
    deviceId = get_json.get('deviceId')
    Device_borrow.query.filter_by(id=id).update({'status': 2, 'pay_money': pay_money, 'return_at': get_current_time()})
    Device.query.filter_by(id=deviceId).update({'status': 1})
    db.session.commit()
    return success_api(msg="支付成功，已归还")
